package Bio::Rambam::Proteomics::MzML;
use Moose;
extends 'Bio::Rambam::Proteomics::Formats::Rawdata';
with 'Bio::Rambam::Proteomics::Tools::FileGeneration';
use namespace::autoclean;
use Bio::Rambam::Proteomics::Mgf;
use Bio::Rambam::Proteomics::Ms2;
use Bio::Rambam::Proteomics::Structures::MzMLSpectrum;
use XML::LibXML;
use XML::LibXML::XPathContext;
use Try::Tiny;
use Data::Dumper;

has 'indexes'	=>	(is=>'rw',	isa=>'HashRef[Int]',predicate => 'has_indexes',clearer => 'clear_indexes',);

sub _mzml_iterator{
	my ($self,$format)=@_;
	die "Not indexed mzML. Not yet supported by this library.\n" unless my %indexes=%{$self->_parse_indexes()};
	open FILE,"<",$self->file;
	foreach my $scan(sort { $indexes{$a} <=> $indexes{$b} }  keys %indexes){
		my $index=$indexes{$scan};
		seek(FILE, $index, 0);
		my $text;
		while(<FILE>){
			$text.=$_;
			last if /\<\/spectrum\>/;
		}
		my $spectrum=_create_spectrum($text);
		if($format->isa("Bio::Rambam::Proteomics::Mgf")){
			next if $spectrum->ms_level eq "1";
			$spectrum->translate_spectra;
			$format->add_spectrum_mgf($spectrum);	
		}
		if($format->isa("Bio::Rambam::Proteomics::Ms2")){
			next if $spectrum->ms_level eq "1";
			$spectrum->translate_spectra;
			$format->add_spectrum_ms2($spectrum);	
		}
	}
	
}

sub create_mgf{
	my ($self,%opt)=@_;
	my ($output_folder,$output_filename)=_create_outputfile($self->file,'mzML|mzml|MZML','mgf',%opt);
	print "Generating $output_filename in $output_folder...";
	my $mgf_path= $output_folder.$output_filename;
	my $mgf=Bio::Rambam::Proteomics::Mgf->new(file=>$mgf_path);
	$self->_mzml_iterator($mgf);
	print "  OK\n";
	return $mgf;
}

sub create_ms2{
	my ($self,%opt)=@_;
	my ($output_folder,$output_filename)=_create_outputfile($self->file,'mzML|mzml|MZML','ms2',%opt);
	print "Generating $output_filename in $output_folder...";
	my $ms2_path= $output_folder.$output_filename;
	my $ms2=Bio::Rambam::Proteomics::Ms2->new(file=>$ms2_path);
	print "  OK\n";
	$self->_mzml_iterator($ms2);
}

sub _parse_indexes{
	my ($self)=shift;
	my $parser = XML::LibXML->new();
	my $doc    = $parser->parse_file($self->file);
	my $xc = XML::LibXML::XPathContext->new( $doc->documentElement() );
	$xc->registerNs( mzml => 'http://psi.hupo.org/ms/mzml' );
	my $specs=0;
	my %indexes;
	
	foreach my $general_index ($xc->findnodes('//mzml:indexedmzML/mzml:indexList/mzml:index')) {
		my $index_name=$general_index->findvalue('@name');
		if($index_name eq 'spectrum'){
			foreach my $index ($general_index->getElementsByTagName('offset')) {
				my $id_ref=$index->findvalue('@idRef');
				my $index_location=$index->textContent;
				$id_ref=~/scan=(\d+)/;
				my $scan= $1;
				$indexes{$specs}=$index_location;
				$specs++;
			}
		}
	}
	$self->indexes(\%indexes);
}

sub _create_spectrum{
	my $spectrum_string=shift;
	my $spectrum=Bio::Rambam::Proteomics::Structures::MzMLSpectrum->new(text_mzML=>$spectrum_string);
	return $spectrum;
}


__PACKAGE__->meta->make_immutable;